昨天已經將 ORM 的優缺點及為何要將 ORM Store Procedure 化的緣由都說明清楚。但是說來容易,如何實作? 雖然之前也有根據 MS-SQL 及 MariaDB 有說明入門及進階的 SQL 語法,但是寫 ORM 可不是件簡單的活,沒有三兩三,怎敢上梁山。
下面我再分別補充將 ORM Store Procedure 化會用到的更進階 SQL 語法。事實上,最核心的程式就是用來執行 [動態 SQL 指令]。
MS-SQL
execute sp_executesql @sql;
MySQL(MariaDB)
PREPARE runsql FROM @sql;
EXECUTE runsql;
MS-SQL
declare @sql nvarchar(max);
if @action = 'C' or @action = 'Insert'
set @sql = 'Insert Into ' + @tablename + ' (' + @fields + ')' + ' Values (' + @datas + ')'
else if @action = 'U' or @action = 'Update'
set @sql = 'update ' + @tablename + ' set ' + @updatedatas + ' where ' + @pkwhere
else if @action = 'D' or @action = 'Delete'
set @sql = 'delete from ' + @tablename + ' where ' + @pkwhere;
begin try
execute sp_executesql @sql;
end try
begin catch
-- Execute the error retrieval routine.
-- 或是也可 SELECT ERROR_NUMBER() AS ErrorNumber, ERROR_MESSAGE() AS ErrorMessage;
execute usp_GetErrorInfo;
end catch
MariaDB
set _uuid2 = uuid();
if _wheresql = '' then
set @sql = concat('Insert Into _split (guid, col) select ', char(39), _uuid2, char(39),
',count(*) from ', _tablename);
else
/* 這裡應該也要考慮 jointables 的寫法(如果 _wheresql 有 ma. _tablename 就要加) */
if position('ma.' in _wheresql) > 0 then
set @sql = concat('Insert Into _split (guid, col) select ', char(39), _uuid2, char(39),
',count(*) from ', _tablename, ' ma where ', _wheresql);
else
set @sql = concat('Insert Into _split (guid, col) select ', char(39), _uuid2, char(39),
',count(*) from ', _tablename, ' where ', _wheresql);
end if;
end if;
/* select @sql; */
PREPARE runsql FROM @sql;
set SQL_SAFE_UPDATES = 0;
EXECUTE runsql;
DEALLOCATE PREPARE runsql;
MySQL(MariaDB) 的語法有一個坑要小心,請小心繞道。
set SQL_SAFE_UPDATES = 0;
另外關於 Error Handle,MS-SQL 的機制很完整,但是 MySQL(MariaDB 就有點遜)
PS:也有可能是我對 MariaDB 還不熟。
/*
MySQL 的 Error Handel 目前只找到以下的寫法, 還想不到共用 function 的寫法
*/
DECLARE CONTINUE HANDLER FOR 1048
begin
set _errcode = '1048';
set _errmsg = '主鍵值不能為空白或 null';
end;
DECLARE CONTINUE HANDLER FOR 1062
begin
set _errcode = '1062';
set _errmsg = '主鍵值重複,無法存檔!!';
end;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
begin
-- set _errcode = '9999';
-- set _errmsg = '資料庫操作失敗, 請洽客服工程師協助';
GET DIAGNOSTICS CONDITION 1
_errcode = RETURNED_SQLSTATE, _errmsg = MESSAGE_TEXT;
end;
要將 ORM Store Procedure 化並不是非常困難的事,對 SQL 語法有一定的理解就不會太難。一旦寫好,您會發現帶來的效益非常巨大,基本的 CRUD 真的在彈指間就完成(當然,前端的程式也要組出對應的內容再呼叫 API),對開發資訊系統的效率,有非常大的提升。今天我們先談到這邊,明天會將 ORM 應具備的功能做詳細說明,並會配合幾個實際的前端呼叫的程式片段來說明,明天見。